<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>我的技术与生活——基于Vue对主题修改的思考与实现 | Hexo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <link rel="shortcut icon" href="../../../../imgs/shortcut-icon.ico" type="image/x-icon">
  <link rel="stylesheet" href="../../../../css/public.css" />
  <link rel="stylesheet" href="../../../../css/layout.css" />
  <link rel="stylesheet" href="../../../../css/iconfont.css" />
  <link rel="stylesheet" href="../../../../css/APlayer.min.css" />
  <script src="../../../../js/APlayer.min.js"></script>
  <script src="../../../../js/jquery.min.js"></script>
  <script src="../../../../js/jquery.pjax.min.js"></script>

  <script src='//unpkg.com/valine/dist/Valine.min.js'></script>
  <script>
    document.title = `我的技术与生活——基于Vue对主题修改的思考与实现`
  </script>
<meta name="generator" content="Hexo 6.0.0"></head>

<style>
  .load {
    width: 100%;
    height: 100vh;
    background-color: rgb(37, 35, 40);
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    position: relative;
    z-index: 9999;
  }
  .load-circle {
    width: 80px;
    height: 80px;
    border: 8px solid orange;
    border-bottom-color: transparent;
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    animation: rotate 1s linear infinite;
    filter: drop-shadow(0 0 3px orange);
  }
  .load-circle-inner {
    width: 40px;
    height: 40px;
    border: 8px solid orange;
    border-top-color: transparent;
    border-radius: 50%;
    animation: rotate-reverse .5s linear infinite;
  }
  .load-text {
    margin-top: 20px;
    font-size: 24px;
    color: orange;
    display: flex;
  }
  .load-text span {
    margin: 0 5px;
    text-shadow: 5px 5px 5px orange;
    animation: move 1s linear infinite;
  }
  .load-text span:nth-child(1) {
    animation-delay: -0.6s;
  }
  .load-text span:nth-child(2) {
    animation-delay: -0.5s;
  }
  .load-text span:nth-child(3) {
    animation-delay: -0.4s;
  }
  .load-text span:nth-child(4) {
    animation-delay: -0.3s;
  }
  .load-text span:nth-child(5) {
    animation-delay: -0.2s;
  }
  .load-text span:nth-child(6) {
    animation-delay: -0.1s;
  }
  @keyframes rotate {
    0% { transform: rotate(0); }
    100% { transform: rotate(360deg); }
  }
  @keyframes rotate-reverse {
    0% { transform: rotate(0); }
    100% { transform: rotate(-360deg); }
  }
  @keyframes move {
    0% { transform: translateY(0%) rotate(0) scale(1); }
    20% { transform: translateY(20%) rotate(10deg) scale(1.2); }
    80% { transform: translateY(-10%) rotate(-20deg) scale(.8);}
    100% { transform: translateY(0) rotate(0) scale(1); }
  }

  .progress {
    position: fixed;
    left: 0; top: 0;
    width: 0;
    height: 3px;
    background-color: green;
    transition: all cubic-bezier(0.215, 0.610, 0.355, 1) .1s;
    z-index: 9999;
  }

  .to-up {
    animation: toUp .5s 1;
  }
  .gray {
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    height: 100vh;
    z-index: 9999;
    display: none;
    pointer-events: none;
    background-color: #000;
    mix-blend-mode: color;
  }
  @keyframes toUp {
    from { transform: translateY(15px); opacity: 0; }
    to { transform: translateY(0) ; opacity: 1; }
  }
</style>
<body>
  <div id="load" class="load">
    <div class="load-circle">
      <div class="load-circle-inner"></div>
    </div>
    <p class="load-text">
      <span>L</span>
      <span>O</span>
      <span>A</span>
      <span>D</span>
      <span>I</span>
      <span>N</span>
      <span>G</span>
    </p>
  </div>
  <div id="container" class="container w-100 vh-100" style="display: none;">
    <header class="header">
  <div class="header-wrapper">
    <div class="header-left">
      <div class="header-search">
        <input id="search-input" type="text" class="header-search--input" placeholder="请输入要检索的文章标题" />
        <span id="search-btn" class="header-search--icon"><i class="iconfont icon-sousuo"></i></span>
      </div>
      <div id="search-layer" class="header-search--layer hidden">
        <p class="title">
          <span>以下是搜索内容：</span>
          <span id="close-layer-btn">关闭</span>
        </p>
        <ul>
        </ul>
      </div>
    </div>
    <div class="header-right">
      <ul class="header-menu">
        <li>
          <a href="https://aizener.github.io/">
            <i class="header-menu--icon iconfont icon-shouye"></i>
            <span class="header-menu--span">首页</span>
          </a>
        </li>
        <li>
          <a href="https://aizener.github.io/log">
            <i class="header-menu--icon iconfont icon-rizhi"></i>
            <span class="header-menu--span">日志</span>
          </a>
        </li>
        <li>
          <a href="https://aizener.github.io/link">
            <i class="header-menu--icon iconfont icon-youqinglianjie"></i>
            <span class="header-menu--span">友情链接</span>
          </a>
        </li>
        <li>
          <a href="https://aizener.github.io/about">
            <i class="header-menu--icon iconfont icon-guanyuwomen"></i>
            <span class="header-menu--span">关于我</span>
          </a>
        </li>
      </ul>
    </div>
  </div>
</header>

<script>
  const ipt = document.querySelector('#search-input')
  const btn = document.querySelector('#search-btn')
  const layer = document.querySelector('#search-layer')
  const posts = JSON.parse(`[{"title":"关于H5新特性拖放API讲解","path":"2022/03/24/关于H5新特性拖放API讲解/"},{"title":"分享基于H5实现扫码功能","cover":"https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9c64349191a94bf19bcaeb14a62d328c~tplv-k3u1fbpfcp-zoom-crop-mark:3024:3024:3024:1702.awebp?","path":"2022/08/14/分享基于H5实现扫码功能/"},{"title":"在Vue项目中使用ESLint来检查代码","cover":"https://s3.bmp.ovh/imgs/2022/04/01/647275ce2adecce7.png","path":"2022/03/02/在Vue项目中使用ESLint来检查代码/"},{"title":"如何使用hexo-theme-cola主题","path":"2022/02/17/如何使用hexo-theme-cola主题/"},{"title":"基于Vue对主题修改的思考与实现","cover":"https://s3.bmp.ovh/imgs/2022/04/01/7d831a8e4b739ac2.png","path":"2022/04/01/基于Vue对主题修改的思考与实现/"},{"title":"趣味NodeJS之笔趣阁的小蜘蛛","cover":"https://s3.bmp.ovh/imgs/2022/04/01/05822287376d328d.png","path":"2022/03/08/趣味NodeJS之笔趣阁的小蜘蛛/"}]`)
  ipt.addEventListener('keyup', e => {
    if (e.key === 'Enter') {
      handleSearch()
    }
  })
  btn.addEventListener('click', () => {
    handleSearch()
  })

  document.querySelector('#close-layer-btn').addEventListener('click', () => {
    layer.classList.toggle('hidden')
  })

  function handleSearch() {
    if (ipt.value.trim() === '') {
      return
    }
    let html = ''
    const targetPosts = posts.filter(post => post.title.includes(ipt.value))
    targetPosts.forEach(post => {
      html += `
        <li>
          <div>
            <a href="/${post.path}">${post.title.replace(new RegExp(ipt.value), `<span>${ipt.value}</span>`)}</a>
          </div>
          <img src="${post.cover || '/imgs/default-cover.webp' }" />
        </li>
      `
    })
    if (html.trim () === '') {
      html += '<p class="empty">没有搜索到内容</p>'
    }
    layer.querySelector('ul').innerHTML = html
    layer.classList.remove('hidden')
  }
</script> 
    <section id="main" class="main">
      <div class="main-left-wrapper">
<div class="main-left">
  <div class="main-left--block">
    <div class="main-left--info">
      <img src="../../../../imgs/avatar.jpg"" class="main-left--avatar" />
      <div class="main-left--intro">
        <p class="main-left--name">Cola.</p>
        <div class="main-left--tags">
          <span class="main-left--tag">中二</span>
          <span class="main-left--tag">宅</span>
        </div>
      </div>
    </div>
  
    <div>
      <div class="main-left--motto">
        <p>“花有重开日，人无再少年”</p>
        <p>“一个简单普通的男孩”</p>
      </div>
      <div class="main-left--github">
        <span class="line"></span>
        <a target="_blank" rel="noopener" href="https://github.com/Aizener"><i class="logo iconfont icon-github-fill"></i></a>
        <span class="line"></span>
      </div>
      <div class="main-left--statics">
        <a href="/categories">
          <div>
            <span>2</span>
            <span>分类</span>
          </div>
        </a>
        <a href="/tags">
          <div>
            <span>7</span>
            <span>标签</span>
          </div>
        </a>
        <a href="/archives">
          <div>
            <span>4 </span>
            <span>归档</span>
          </div>
        </a>
      </div>
    </div>
  </div>

  <div class="main-left--block">
    <ul class="main-left--menu">
      
        <li>
          <a href="/">
            <span class="header-menu--span">小站首页</span>
            <i class="header-menu--icon iconfont icon-shouye"></i>
          </a>
        </li>
      
        <li>
          <a href="/log">
            <span class="header-menu--span">个人日志</span>
            <i class="header-menu--icon iconfont icon-rizhi"></i>
          </a>
        </li>
      
        <li>
          <a href="/link">
            <span class="header-menu--span">友情链接</span>
            <i class="header-menu--icon iconfont icon-youqinglianjie"></i>
          </a>
        </li>
      
        <li>
          <a href="/about">
            <span class="header-menu--span">关于自己</span>
            <i class="header-menu--icon iconfont icon-guanyuwomen"></i>
          </a>
        </li>
      
        <li>
          <a href="/tools">
            <span class="header-menu--span">我的工具</span>
            <i class="header-menu--icon iconfont icon-gongju"></i>
          </a>
        </li>
      
    </ul>
  </div>

  <div class="main-left--block">
    <div class="main-left--site">
      <h5 class="main-left--title">
        <span>站点信息</span>
        <i class="iconfont icon-zhandian"></i>
      </h5>
      <p class="main-left--subtitle">
        <span>文章数目：</span>
        <span>6 篇</span>
      </p>
      <p class="main-left--subtitle">
        <span>最近动态：</span>
        <span>6月前</span>
      </p>
      <p class="main-left--subtitle">
        <span>上线时间：</span>
        <span>410天</span>
      </p>
      <p class="main-left--subtitle">
        <span>当前版本：</span>
        <span>v1.0.2</span>
      </p>
    </div>
  </div>
</div></div>
      <div id="main-container" class="main-container">


  <style>
pre::-webkit-scrollbar {
  width: 5px;
  height: 10px;
  background-color:#F5F5F5;
}
/*定义滚动条轨道
内阴影+圆角*/
pre::-webkit-scrollbar-track {
  background-color:#F5F5F5;
}
/*定义滑块
内阴影+圆角*/
pre::-webkit-scrollbar-thumb {
  background-color: rgb(69, 83, 100);
}

pre:active {
  background-color: rgb(81, 95, 116);
}
</style>

<div class="article-container">
  <div class="article">
    <h1 class="article-title">基于Vue对主题修改的思考与实现</h1>
    <div class="article-info">
      <div class="article-info--item">
        <div class="article-info--info">
          
          <div class="article-info--categories">
            <span>分类：</span>
            <a class="category-link" href="../../../../categories/Web%E5%89%8D%E7%AB%AF/">Web前端</a>
          </div>
          
          
          <div class="article-info--tags">
            <span>标签：</span>
            <a class="tag-link" href="../../../../tags/CSS/" rel="tag">CSS</a><a class="tag-link" href="../../../../tags/Vue/" rel="tag">Vue</a>
          </div>
          
          <p class="article-info--date">日期：2022-04-01 22:52:19</p>
        </div>
        <img src="https://s3.bmp.ovh/imgs/2022/04/01/7d831a8e4b739ac2.png" alt="" class="article-cover">
      </div>
    </div>
    <article class="article-content">
      <blockquote>
<p>主题更改虽然不是一个常用的功能，但是我还是想了解一下这个东西的思路和实现，个人思考之后，觉得就是动态绑定style的方法比较容易，特此记录。</p>
</blockquote>
<p>先看看效果：  </p>
<p><img src="https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0117af83c3a0477e8c0205677854244a~tplv-k3u1fbpfcp-watermark.image" alt="nicec.gif"></p>
<h3 id="CSS函数之var"><a href="#CSS函数之var" class="headerlink" title="CSS函数之var"></a>CSS函数之var</h3><p>在敲代码之前，先说一下<code>var</code>函数。</p>
<p><code>var</code>函数作为<code>css</code>的新特性之一，是用于插入自定义的属性值；</p>
<p>如果一个属性值在多处被使用，该方法就很有用，看一下demo：</p>
<pre class="line-numbers language-none"><code class="language-none">:root &#123;
  --main-bg-color: coral;
&#125;
 
#div1 &#123;
  background-color: var(--main-bg-color);
&#125;
 
#div2 &#123;
  background-color: var(--main-bg-color);
&#125;<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>根据这个<code>var</code>函数，我们就可以事先定义一堆属性，然后给需要修改主题的地方赋值，这样就很方便了。</p>
<p>但是这个属性并不兼容<code>IE</code>等一些小众浏览器，看下图：</p>
<p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/909377d3853d4a408d007b74a2e3cd43~tplv-k3u1fbpfcp-watermark.image" alt="error"></p>
<p>所以考虑兼容性的话，就不能使用<code>var</code>函数了，而是一个地方一个地方动态设置样式。</p>
<h3 id="配置主题"><a href="#配置主题" class="headerlink" title="配置主题"></a>配置主题</h3><p>主题应该是有一个或多个配置文件来定义的，可以是JS文件导出，也可以是JSON文件，当然也可以从后端请求回来：</p>
<pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">&#123;</span>
  <span class="token keyword">default</span><span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    <span class="token string">'link-color'</span><span class="token operator">:</span> <span class="token string">'green'</span><span class="token punctuation">,</span>
    <span class="token string">'text-color'</span><span class="token operator">:</span> <span class="token string">'black'</span><span class="token punctuation">,</span>
    <span class="token string">'body-bg'</span><span class="token operator">:</span> <span class="token string">'#fff'</span><span class="token punctuation">,</span>
    <span class="token string">'logo-filter'</span><span class="token operator">:</span> <span class="token string">'brightness(1)'</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
  dark<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    <span class="token string">'link-color'</span><span class="token operator">:</span> <span class="token string">'#fff'</span><span class="token punctuation">,</span>
    <span class="token string">'text-color'</span><span class="token operator">:</span> <span class="token string">'orange'</span><span class="token punctuation">,</span>
    <span class="token string">'body-bg'</span><span class="token operator">:</span> <span class="token string">'#666'</span><span class="token punctuation">,</span>
    <span class="token string">'logo-filter'</span><span class="token operator">:</span> <span class="token string">'brightness(2)'</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
  light<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    <span class="token string">'link-color'</span><span class="token operator">:</span> <span class="token string">'skyblue'</span><span class="token punctuation">,</span>
    <span class="token string">'text-color'</span><span class="token operator">:</span> <span class="token string">'green'</span><span class="token punctuation">,</span>
    <span class="token string">'body-bg'</span><span class="token operator">:</span> <span class="token string">'aliceblue'</span><span class="token punctuation">,</span>
    <span class="token string">'logo-filter'</span><span class="token operator">:</span> <span class="token string">'brightness(3)'</span>
  <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>这是我随便定义的一些主题色（很丑噶），我的思路就是每一个<code>Key</code>就是主题的名称，通过修改<code>Key</code>来得到不同的主题状态，从而更换网站的主题色。</p>
<p>因为主题基本都是影响多个页面的，所以这里我们需要引入<code>Vuex</code>来保存当前主题状态。</p>
<h3 id="引入Vuex"><a href="#引入Vuex" class="headerlink" title="引入Vuex"></a>引入Vuex</h3><p>引入<code>Vuex</code>后，我们需要设置一个<code>theme</code>属性来表示当前的主题状态，同样的会提供对应的<code>mutations</code>和<code>actions</code>里面的方法来修改这个<code>theme</code>属性。</p>
<pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token keyword">import</span> Vue <span class="token keyword">from</span> <span class="token string">'vue'</span>
<span class="token keyword">import</span> Vuex <span class="token keyword">from</span> <span class="token string">'vuex'</span>
<span class="token keyword">import</span> themes <span class="token keyword">from</span> <span class="token string">'../themes/index'</span>
​
Vue<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>Vuex<span class="token punctuation">)</span>
​
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">new</span> <span class="token class-name">Vuex<span class="token punctuation">.</span>Store</span><span class="token punctuation">(</span><span class="token punctuation">&#123;</span>
  state<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    theme<span class="token operator">:</span> <span class="token string">'default'</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
  getters<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    <span class="token function">currTheme</span><span class="token punctuation">(</span><span class="token parameter">state</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
      <span class="token keyword">return</span> themes<span class="token punctuation">[</span>state<span class="token punctuation">.</span>theme<span class="token punctuation">]</span>
    <span class="token punctuation">&#125;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
  mutations<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    <span class="token constant">UPDATE_THEME</span><span class="token punctuation">(</span><span class="token parameter">state<span class="token punctuation">,</span> theme</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
      state<span class="token punctuation">.</span>theme <span class="token operator">=</span> theme
    <span class="token punctuation">&#125;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
  actions<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    <span class="token function">updateTheme</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">&#123;</span> commit <span class="token punctuation">&#125;</span><span class="token punctuation">,</span> theme</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
      <span class="token function">commit</span><span class="token punctuation">(</span><span class="token string">'UPDATE_THEME'</span><span class="token punctuation">,</span> theme<span class="token punctuation">)</span>
    <span class="token punctuation">&#125;</span>
  <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span class="token punctuation">)</span>
​<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>

<p>上面还可以看到，我们还使用了<code>getters</code>这个对象，使用这个对象可以很方便的依赖<code>state</code>的变化而更新对应的主题状态，而我们只管修改<code>state</code>的属性即可。</p>
<h3 id="设置CSS变量"><a href="#设置CSS变量" class="headerlink" title="设置CSS变量"></a>设置CSS变量</h3><p>因为我们要设置CSS的变量供其他页面使用<code>var</code>函数调用，所以一般设置在顶层组件，我们可以再<code>App.vue</code>里面设置：</p>
<pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token operator">&lt;</span>template<span class="token operator">></span>
  <span class="token operator">&lt;</span>div id<span class="token operator">=</span><span class="token string">"app"</span> <span class="token operator">:</span>style<span class="token operator">=</span><span class="token string">"themeStyle"</span><span class="token operator">></span>
    <span class="token operator">&lt;</span>img alt<span class="token operator">=</span><span class="token string">"Vue logo"</span> src<span class="token operator">=</span><span class="token string">"./assets/logo.png"</span><span class="token operator">></span>
    <span class="token operator">&lt;</span>HelloWorld msg<span class="token operator">=</span><span class="token string">"Welcome to Your Vue.js App"</span><span class="token operator">/</span><span class="token operator">></span>
  <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span>
<span class="token operator">&lt;</span><span class="token operator">/</span>template<span class="token operator">></span>
​
<span class="token operator">&lt;</span>script<span class="token operator">></span>
<span class="token keyword">import</span> HelloWorld <span class="token keyword">from</span> <span class="token string">'./components/HelloWorld.vue'</span>
<span class="token keyword">import</span> <span class="token punctuation">&#123;</span> mapActions<span class="token punctuation">,</span> mapGetters <span class="token punctuation">&#125;</span> <span class="token keyword">from</span> <span class="token string">'vuex'</span>
<span class="token keyword">import</span> themes <span class="token keyword">from</span> <span class="token string">'./themes/index'</span>
​
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">&#123;</span>
  name<span class="token operator">:</span> <span class="token string">'App'</span><span class="token punctuation">,</span>
  components<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    HelloWorld
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
  computed<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    <span class="token operator">...</span><span class="token function">mapGetters</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">'currTheme'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token function">themeStyle</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
      <span class="token keyword">const</span> themeStyle <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span>
      <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> key <span class="token keyword">in</span> <span class="token keyword">this</span><span class="token punctuation">.</span>currTheme<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        themeStyle<span class="token punctuation">[</span><span class="token string">'--theme-'</span> <span class="token operator">+</span> key<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>currTheme<span class="token punctuation">[</span>key<span class="token punctuation">]</span>
      <span class="token punctuation">&#125;</span>
      <span class="token keyword">return</span> themeStyle
    <span class="token punctuation">&#125;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
  methods<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    <span class="token operator">...</span><span class="token function">mapActions</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">'updateTheme'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token function">handleChange</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateTheme</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>currentTarget<span class="token punctuation">.</span>value<span class="token punctuation">)</span>
    <span class="token punctuation">&#125;</span>
  <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>通过样式动态绑定的方式，我们就给<code>div#app</code>标签绑定上了CSS变量，可以看到如下图：</p>
<p><img src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/00828da640354dc4a9fb4d8dabd7b16e~tplv-k3u1fbpfcp-watermark.image" alt="error"></p>
<p>接着，要在需要随主题变化的元素设置对应主题色就行了，例如：</p>
<pre class="line-numbers language-css" data-language="css"><code class="language-css"><span class="token selector">p, h1, h2, h3</span> <span class="token punctuation">&#123;</span>
  <span class="token property">color</span><span class="token punctuation">:</span> <span class="token function">var</span><span class="token punctuation">(</span>--theme-text-color<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<p>如果，考虑兼容性的话，就通过动态绑定吧，这样会繁琐一些。</p>
<h3 id="主题切换"><a href="#主题切换" class="headerlink" title="主题切换"></a>主题切换</h3><p>此时，我们只需要提供修改<code>state</code>的<code>theme</code>属性方式，就可以完成主题的修改啦，例如通过<code>select</code>来选择后修改<code>theme</code>属性：</p>
<pre class="line-numbers language-js" data-language="js"><code class="language-js"><span class="token operator">&lt;</span>template<span class="token operator">></span>
  <span class="token operator">&lt;</span>div id<span class="token operator">=</span><span class="token string">"app"</span> <span class="token operator">:</span>style<span class="token operator">=</span><span class="token string">"themeStyle"</span><span class="token operator">></span>
    <span class="token operator">&lt;</span>img alt<span class="token operator">=</span><span class="token string">"Vue logo"</span> src<span class="token operator">=</span><span class="token string">"./assets/logo.png"</span><span class="token operator">></span>
    <span class="token operator">&lt;</span>HelloWorld msg<span class="token operator">=</span><span class="token string">"Welcome to Your Vue.js App"</span><span class="token operator">/</span><span class="token operator">></span>
    <span class="token operator">&lt;</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"switch"</span><span class="token operator">></span>
      切换主题：
      <span class="token operator">&lt;</span><span class="token operator">!</span><span class="token operator">--</span> 可以通过遍历来生成 <span class="token operator">--</span><span class="token operator">></span>
      <span class="token operator">&lt;</span>select @change<span class="token operator">=</span><span class="token string">"handleChange"</span><span class="token operator">></span>
        <span class="token operator">&lt;</span>option value<span class="token operator">=</span><span class="token string">"default"</span><span class="token operator">></span><span class="token keyword">default</span><span class="token operator">&lt;</span><span class="token operator">/</span>option<span class="token operator">></span>
        <span class="token operator">&lt;</span>option value<span class="token operator">=</span><span class="token string">"dark"</span><span class="token operator">></span>dark<span class="token operator">&lt;</span><span class="token operator">/</span>option<span class="token operator">></span>
        <span class="token operator">&lt;</span>option value<span class="token operator">=</span><span class="token string">"light"</span><span class="token operator">></span>light<span class="token operator">&lt;</span><span class="token operator">/</span>option<span class="token operator">></span>
      <span class="token operator">&lt;</span><span class="token operator">/</span>select<span class="token operator">></span>
    <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span>
  <span class="token operator">&lt;</span><span class="token operator">/</span>div<span class="token operator">></span>
<span class="token operator">&lt;</span><span class="token operator">/</span>template<span class="token operator">></span>
​
<span class="token operator">&lt;</span>script<span class="token operator">></span>
<span class="token keyword">import</span> HelloWorld <span class="token keyword">from</span> <span class="token string">'./components/HelloWorld.vue'</span>
<span class="token keyword">import</span> <span class="token punctuation">&#123;</span> mapActions<span class="token punctuation">,</span> mapGetters <span class="token punctuation">&#125;</span> <span class="token keyword">from</span> <span class="token string">'vuex'</span>
​
<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">&#123;</span>
  name<span class="token operator">:</span> <span class="token string">'App'</span><span class="token punctuation">,</span>
  components<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    HelloWorld
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
  computed<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    <span class="token operator">...</span><span class="token function">mapGetters</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">'currTheme'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token function">themeStyle</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
      <span class="token keyword">const</span> themeStyle <span class="token operator">=</span> <span class="token punctuation">&#123;</span><span class="token punctuation">&#125;</span>
      <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> key <span class="token keyword">in</span> <span class="token keyword">this</span><span class="token punctuation">.</span>currTheme<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        themeStyle<span class="token punctuation">[</span><span class="token string">'--theme-'</span> <span class="token operator">+</span> key<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>currTheme<span class="token punctuation">[</span>key<span class="token punctuation">]</span>
      <span class="token punctuation">&#125;</span>
      <span class="token keyword">return</span> themeStyle
    <span class="token punctuation">&#125;</span>
  <span class="token punctuation">&#125;</span><span class="token punctuation">,</span>
  methods<span class="token operator">:</span> <span class="token punctuation">&#123;</span>
    <span class="token operator">...</span><span class="token function">mapActions</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string">'updateTheme'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token function">handleChange</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
      <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">updateTheme</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>currentTarget<span class="token punctuation">.</span>value<span class="token punctuation">)</span>
    <span class="token punctuation">&#125;</span>
  <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">></span>
​<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><p>修改主题的方式还有其他的，比如通过<code>less</code>的<code>modifyVars</code>也可以完成（没看懂怎么费事），但是我觉得动态绑定<code>style</code>的方式比较好理解，不考虑兼容<code>ie</code>使用<code>var</code>函数还是很方便的，倘若考虑兼容就得累一点一个个动态绑定了。</p>

    </article>
    
    <div class="read-nums">
      <!-- id 将作为查询条件 -->
      <span id="2022/04/01/基于Vue对主题修改的思考与实现/" class="leancloud_visitors" data-flag-title="Your Article Title">
        <em class="post-meta-item-text">浏览量</em>
        <i class="leancloud-visitors-count"></i>
      </span>
    </div>
    <div class="comments-intro">
      <h2>评论区</h2>
      <p>欢迎你留下宝贵的意见，昵称输入QQ号会显示QQ头像哦~</p>
    </div>
    <div id="vcomments" class="vcomments"></div>
    
  </div>
  <div class="article-catelogue">
    <div class="article-catelogue--wrapper">
      <div class="catelogue catelogue-1">
        <h3>目录</h3>
        <ol class="toc"><li class="toc-item toc-level-3"><a class="toc-link" href="#CSS%E5%87%BD%E6%95%B0%E4%B9%8Bvar"><span class="toc-number">1.</span> <span class="toc-text">CSS函数之var</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%85%8D%E7%BD%AE%E4%B8%BB%E9%A2%98"><span class="toc-number">2.</span> <span class="toc-text">配置主题</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%BC%95%E5%85%A5Vuex"><span class="toc-number">3.</span> <span class="toc-text">引入Vuex</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AE%BE%E7%BD%AECSS%E5%8F%98%E9%87%8F"><span class="toc-number">4.</span> <span class="toc-text">设置CSS变量</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%BB%E9%A2%98%E5%88%87%E6%8D%A2"><span class="toc-number">5.</span> <span class="toc-text">主题切换</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%80%BB%E7%BB%93"><span class="toc-number">6.</span> <span class="toc-text">总结</span></a></li></ol>
      </div>
      
        <div class="catelogue catelogue-2">
          
            <p>
              <span>上一篇：</span>
              <a href="/2022/08/14/分享基于H5实现扫码功能/">分享基于H5实现扫码功能</a>
            </p>
           
          
            <p>
              <span>下一篇</span>
              <a href="/2022/03/24/关于H5新特性拖放API讲解/">关于H5新特性拖放API讲解</a>
            </p>
          
        </div>
      
    </div>
  </div>
</div>

<script src="http://cdn.yangxiang.cc/prism.js"></script>

<script>
  // var定义，避免pjax重新进来造成的重复声明错误
  var config = JSON.parse('{"enable":true,"appId":"Pf8zCXGEH1qsprnWfikVVujL-gzGzoHsz","appKey":"qOqoiUHhH1TGtLRUYURkLRQX","placeholder":"请留下你宝贵的意见吧~","meta":["nick"],"recordIP":true,"visitor":true,"enableQQ":true}')
  new Valine({
    el: '#vcomments',
    appId: config.appId,
    appKey: config.appKey,
    placeholder: config.placeholder,
    meta: config.meta,
    recordIP: config.recordIP,
    visitor: config.visitor,
    enableQQ: config.enableQQ,
    path: '2022/04/01/基于Vue对主题修改的思考与实现/'
  })
</script>


<script>
  $(document).on('pjax:complete', function() {
    const tocs = document.querySelector('.toc')
    const links = tocs ? tocs.querySelectorAll('a') : []
    links.forEach(link => {
      link.addEventListener('click', e => {
        const href = decodeURIComponent(a.href)
        href.search(/#(.*)/)
        const id = RegExp.$1
        const target = document.querySelector('#' + id)
        const top = target.offsetTop
        document.documentElement.scrollTo({
          top: top - 100,
          behavior: 'smooth'
        })
        e.preventDefault()
      })
    })
  })
</script> 

</div>
      <div class="main-right-wrapper"><div class="main-right">
  <div class="main-right--board">
    <div class="main-right--title">
      <h5>公告栏</h5>
      <i class="iconfont icon-gonggao"></i>
    </div>
    <div class="main-right--content">
      Hello~大噶好。唔系可乐爱宅着，欢迎你们来到我的博客小站，希望能在这里收获到有用的东西哦！ 
    </div>
  </div>

  <div id="aplayer" class="main-right--music"></div>

  <div class="operate-items">
    <div class="operate-item backtop">
      <i class="iconfont icon-huidaodingbu"></i>
      <span>回到顶部</span>
    </div>
    
    <div class="operate-item turn-comment hidden">
      <i class="iconfont icon-pinglun"></i>
      <span>查看评论</span>
    </div>
    
  </div>

  <div class="main-right--site">
    <div class="main-right--power">
      <p>Power By <a target="_blank" rel="noopener" href="https://hexo.io/zh-cn/docs/">Hexo</a>.</p>
      <p>Theme：<a target="_blank" rel="noopener" href="https://github.com/Aizener/hexo-theme-cola">Cola.</a></p>
    </div>
    <p class="main-right--refer"><a target="_blank" rel="noopener" href="https://beian.miit.gov.cn/#/Integrated/index">蜀ICP备2022005384号-1</a> </p>
  </div>
</div>

<script>
  function setOperateItem () {
    const reg = /\d{4}\/\d{2}\/\d{2}\/.+/
    const path = location.pathname
    const commentDom = document.querySelector('.turn-comment')
    if (commentDom) {
      if (reg.test(path) || path.match(/\/log\/.+/)) {
        commentDom.classList.remove('hidden')
      } else {
        commentDom.classList.add('hidden')
      }
    }
  }

  setOperateItem()
  const musics = JSON.parse(`[{"name":"安河桥","artist":"宋冬野","url":"http://ting6.yymp3.net:82/new25/songdongye/11.mp3","cover":"https://img2.baidu.com/it/u=1260056724,1076343118&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500"},{"name":"卡布达","artist":"暂无","url":"music/kabuda.mp3","cover":"https://img2.baidu.com/it/u=705831265,2862720033&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500"}]`)
  const ap = new APlayer({
    container: document.querySelector('#aplayer'),
    audio: musics,
  })

  $(document).on('pjax:complete', function() {
    setOperateItem()
  })

  document.querySelector('.backtop').addEventListener('click', () => {
    document.documentElement.scrollTo({
      top: 0,
      behavior: 'smooth'
    })
  })
  const dom = document.querySelector('.turn-comment')
  dom && dom.addEventListener('click', () => {
    const commentDom = document.querySelector('.comments-intro')
    if (!commentDom) return
    const top = commentDom.offsetTop, height = commentDom.offsetHeight
    document.documentElement.scrollTo({
      top: top - 2 * height,
      behavior: 'smooth'
    })
  })
</script></div>
    </section>
  </div>
  <div id="progress" class="progress"></div>
  <div id="gray" class="gray"></div>

  <script>
    function initScroll () {
      document.addEventListener('scroll', () => {
        const doc = document.documentElement
        const scrollTop = doc.scrollTop
        const pageHeight = doc.offsetHeight
        const clientHeight = doc.clientHeight
        const ratio = scrollTop / (pageHeight - clientHeight)
        const progress = document.querySelector('#progress')
        const avatarImg = document.querySelector('.main-left--avatar')
        progress.style.width = (100 * ratio) + '%'
        avatarImg.style.transform = `rotate(${360 * ratio}deg)`
      })
    }

    const rootPath = "/"

    const checkAndSetArticlePageLayout = () => {
      if (/^\/?\d{4}\/\d{2}\/\d{2}\/.*/.test(location.pathname.replace(rootPath, ''))) {
        $('.main-container, .main-right, .main-right-wrapper').addClass('is-article')
      } else {
        $('.main-container, .main-right, .main-right-wrapper').removeClass('is-article')
      }
    }

    const gray = "none"
    const setGrayStyle = () => {
      if (gray === 'none') {
        return
      } else if (gray === 'index') {
        location.pathname === '/' ? $('#gray').show() : $('#gray').hide()
      } else if (gray === 'all') {
        $('#gray').show()
      }
    }
    setGrayStyle()


    window.onload = function () {
      checkAndSetArticlePageLayout()
      setTimeout(() => {
        $('#load').slideUp()
        $('#container').slideToggle()
        setTimeout(() => {
          initScroll()
        }, 500)
      }, 500)
    }
    
    let status = 0
    // 对所有链接跳转事件绑定pjax容器container
    $(document).pjax('a[target!=_blank]', '#main-container', {
      container: '#main-container',
      fragment: '#main-container',
      timeout: 8000
    })

    $(document).on('pjax:start', function() {
    })
    $(document).on('pjax:complete', function() {
      status = 0
      $('.main-container').addClass('to-up').on('animationend', function() {
        $(this).removeClass('to-up')
      })
      setGrayStyle()
      checkAndSetArticlePageLayout()
    })
    $(document).on('pjax:popstate', function() {
      status = -1
      checkAndSetArticlePageLayout()
      // $('.main-container').fadeIn()
    })
  </script>
</body>
</html>